package main

import (
	"fmt"
	"sync"
	"time"
)

var wg = new(sync.WaitGroup)

func noBuffChannel() {
	// 声明 通道中 元素类型
	var b chan int
	fmt.Println(b)

	// 初始化 通道
	// 通道需初始化后才能使用
	// 一个没有缓冲区的通道
	b = make(chan int)
	fmt.Println(b)

	wg.Add(1)
	// 由另一个 goroutine 负责接收
	go func() {
		fmt.Println("goroutine 接收: 等待接收 通道 b 中的值")
		// 从通道 b 接收一个值
		t := <-b
		fmt.Printf("goroutine 接收: %d\n", t)

		// 关闭通道
		close(b)

		wg.Done()
	}()

	wg.Add(1)
	go func() {
		time.Sleep(500 * time.Millisecond)
		fmt.Println("goroutine 发送: 将 10086 发送到 通道 b 中")
		// 将 10086 发送至 通道 b 中
		// 没人接收将会导致死锁
		b <- 10086

		wg.Done()
	}()
}

func buffChannel() {
	// 带缓冲区的通道初始化
	b := make(chan int, 1)

	go func() {
		// 使用 for...range 从通道读取值
		for t := range b {
			fmt.Printf("goroutine 接收: %d\n", t)
		}
	}()

	fmt.Println("goroutine 发送: 将 10086 发送到 通道 b 中")
	b <- 10086

	// 当缓冲区满了 没人接收也会导致死锁
	fmt.Println("goroutine 发送: 将 1008611 发送到 通道 b 中")
	b <- 1008611

	// 关闭通道
	close(b)
}

func main() {
	noBuffChannel()
	wg.Wait()

	fmt.Println("=========================================================")

	buffChannel()
	wg.Wait()
}
